// 新写法定义的属性是实例对象自身的属性，而不是定义在实例对象的原型上面。
/* class IncreasingCounter {
  _count1: any;
  _count2 = 2;

  constructor() {
    this._count1 = 0;
  }

  get value() {
    return this._count1;
  }

  increment() {
    this._count1++;
  }
}
const c1 = new IncreasingCounter();
console.log(c1.value);
c1.increment();
console.log(c1.value);
console.log(c1._count2);
console.log(Object.keys(c1), Object.getOwnPropertyNames(c1));
console.log(Object.getOwnPropertyNames(IncreasingCounter.prototype)); */

// 与 ES5 一样，在“类”的内部可以使用get和set关键字，对某个属性设置存值函数和取值函数，拦截该属性的存取行为
// 存值函数和取值函数是设置在属性的 Descriptor 对象上的。
/* class MyClass {
  constructor() {
    // ...
  }
  get prop() {
    return "getter";
  }
  set prop(value) {
    console.log("setter: " + value);
  }

  get command() {
    throw new Error("command must be implements");
  }

  get description() {
    throw new Error("description must be implements");
  }
}

let inst = new MyClass();
console.log(inst.prop);
inst.prop = "123";
console.log(inst.prop);

var descriptor: any = Object.getOwnPropertyDescriptor(
  MyClass.prototype,
  "prop"
);
console.log(descriptor, "get" in descriptor, "set" in descriptor); // true, true */

// 与函数一样，类也可以使用表达式的形式定义。
// 类的名字是Me，但是Me只在 Class 的内部可用，指代当前类。在 Class 外部，这个类只能用MyClass引用
/* const MyClass = class Me {
  getClassName() {
    console.log(Me.name);
  }
};
let inst = new MyClass();
inst.getClassName(); // Me
// console.log(Me.name); // Cannot find name 'Me' */

// 静态方法
/* class Foo {
  static bar() {
    this.baz();
  }
  static baz() {
    console.log("hello");
  }
  static classMethod() {
    return "hello";
  }
  baz() {
    console.log("world");
  }
}
Foo.bar();

// 父类的静态方法，可以被子类继承。
class Bar extends Foo {
  // 静态方法也是可以从super对象上调用的
  static classMethod() {
    return super.classMethod() + ", too";
  }
}
Bar.bar();
console.log(Bar.classMethod()); */

// 如果某个方法之前加上星号（*），就表示该方法是一个 Generator 函数
/* class Foo {
  args: any;

  constructor(...args: any) {
    this.args = args;
  }

  *[Symbol.iterator]() {
    for (let arg of this.args) {
      yield arg;
    }
  }
}

for (let x of new Foo("hello", "world")) {
  console.log(x);
} */

class Logger {
  constructor() {
    this.printName = this.printName.bind(this);
  }

  printName(name = "there") {
    this.print(`Hello ${name}`);
  }

  print(text: any) {
    console.log(text);
  }
}
const logger = new Logger();
logger.printName();

const { printName } = logger;
printName();

export {};
